from collections import Iterable
from collections import Iterator


class IterableObjectDemo(object):
    def __init__(self):
        self.container = []

    def add(self, item):
        self.container.append(item)

    def __iter__(self):
        pass

    def _test_iterable(self):
        """
        iod = IterableObjectDemo()
        iod._test_iterable()
        """
        iterable_object = IterableObjectDemo()
        print(isinstance(iterable_object, Iterable))
        print(isinstance(iterable_object, Iterator))


class IIterableObjectDemo(object):
    def __init__(self):
        self.container = []

    def add(self, item):
        self.container.append(item)

    def __iter__(self):
        iterator = IteratorDemo(self)
        return iterator

    def _test_iterator(self):
        """
        iiod = IIterableObjectDemo()
        iiod._test_iterator()
        """
        iiod = IIterableObjectDemo()
        iiod.add('nihao')
        iiod.add('hha')
        iiod.add('python')
        for elem in iiod:
            print(elem)


class IteratorDemo(object):
    def __init__(self, mylist):
        self.mylist = mylist
        self.curpos = 0

    def __next__(self):
        if self.curpos < len(self.mylist.container):
            container = self.mylist.container[self.curpos]
            self.curpos += 1
            return container
        else:
            raise StopIteration

    def __iter__(self):
        return self


class IteratorFiboDemo(object):
    def __init__(self, num=5):
        self.num = num
        self.a = 0
        self.b = 1
        self.curpos = 0

    def __iter__(self):
        return IteratorFiboDemo()

    def __next__(self):
        if self.curpos <= self.num:
            result = self.a
            self.a, self.b = self.b, self.a + self.b
            return result
        else:
            raise StopIteration

    def _test_iterator_fibo(self):
        """
        ifd = IteratorFiboDemo()
        ifd._test_iterator_fibo()
        """
        ifd = IteratorFiboDemo(5)
        for i in range(5):
            print(next(ifd))


if __name__ == '__main__':
    ifd = IteratorFiboDemo()
    ifd._test_iterator_fibo()
